package com.faithbj.common.utils;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteWatchdog;

/**
 * shell命令执行工具类
 * 
 * @author chen liu
 */
public abstract class ExecUtil {
    /** environment **/
    public static final String PATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";

    public static int executeWithoutTimeout(String workingDirPath, String command, String[] args) {
        return execute(workingDirPath, command, args, 0);
    }

    public static int executeWithoutTimeout(String workingDirPath, String command) {
        return execute(workingDirPath, command, null, 0);
    }

    public static int execute(String workingDirPath, String command, int timeout) {
        return execute(workingDirPath, command, null, timeout);
    }

    /**
     * 执行shell命令
     * 
     * @param workingDirPath 脚本/命令工作目录
     * @param command 命令
     * @param args 参数
     * @param timeout 超时时间，以秒为单位
     * @return 1:成功;0:执行结果返回失败代码;-1:执行超时;-2:命令调用异常
     */
    public static int execute(String workingDirPath, String command, String[] args, int timeout) {
        // 设置环境变量
        Map<String, String> environment = new HashMap<String, String>();
        environment.put("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin");
        // 生成命令行
        CommandLine cmdLine = CommandLine.parse(command);
        if(args != null){
            for (String arg : args) {
                cmdLine.addArgument(arg);
            } 
        }

        // 配置executor
        DefaultExecutor executor = new DefaultExecutor();
        executor.setWorkingDirectory(new File(workingDirPath));
        executor.setExitValue(0);
        ExecuteWatchdog watchdog = null;
        if (timeout > 0) {
            watchdog = new ExecuteWatchdog(timeout);
            executor.setWatchdog(watchdog);
        }

        try {
            int exitValue = executor.execute(cmdLine, environment);
            if (executor.isFailure(exitValue)) {
                return 0;
            } else if (watchdog != null && watchdog.killedProcess()) {
                return -1;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return -2;
        }
        return 1;
    }
}
